var Q = require('q');

var redis = require('redis');
var redisClientSubscriber = redis.createClient();
var redisClientDataTransfer = redis.createClient();
var redisClientPublisher = redis.createClient();

var redisNameSpace = "totalStationServer"; //redis中的命名空间
redisClientSubscriber.subscribe(redisNameSpace + ":msgFromTps");
redisClientSubscriber.subscribe(redisNameSpace + ":cmdFromTps");

var bufferCaller = require('./bufferCaller');



var WebSocketServer = function() {
    var WebSocketServer = {
        WebClientList: [],
        tempData: [],
        Initial: function(expressServer) {

            var io = require('socket.io');
            var ioSocket = io.listen(expressServer, {
                'log': false
            });
            var WebClients = require('./WebClient.js').WebClients;
            var emmitFactory = require('./emmitFactory.js');
            var emmitter = new emmitFactory(WebSocketServer, redisClientDataTransfer);
            //向tspserver注册本客户
            redisClientSubscriber.on('message', function(channel, data) {
                var jsonData = JSON.parse(data);
                console.log(jsonData);
                if (channel === (redisNameSpace + ':msgFromTps')) {
                    processMsgData(jsonData);
                } else if (channel === (redisNameSpace + ':cmdFromTps')) {
                    processCmdData(jsonData);
                }
            });

            function processJsonData(jsonData) {
                jsonData.cmdData.Target = jsonData.name;
                return jsonData.cmdData;
            }

            function processCmdData(jsonData) {
                var cmdData = processJsonData(jsonData);
                var fn = (function(emmitter, cmdData) {
                    return function() {
                        var func = emmitter[cmdData.Command];
                        func.call(emmitter, cmdData);
                    };
                })(emmitter, cmdData);
                bufferCaller.add(fn, cmdData.Target);
            }

            function processMsgData(jsonData) {
                var cmdData = processJsonData(jsonData);
                var msg = cmdData.Para;
                var func = null;
                if (msg.indexOf('测量指令已下达') >= 0) {
                    var func = emmitter.StartSurvey;
                    func.call(emmitter, cmdData);
                } else if (msg.indexOf('停止指令已下达') >= 0) {
                    bufferCaller.stop(cmdData.Target);
                    var func = emmitter.StopSurvey;
                    func.call(emmitter, cmdData);
                } else if (msg.indexOf('号点') >= 0) {
                    var ptIndex = msg.indexOf('号点');
                    var temp = {
                        curPtName: msg.slice(2, ptIndex),
                        curPrjName: cmdData.Target,
                        curPtValue: 0
                    };
                    //删除现有的
                    for (var i = 0; i < WebSocketServer.tempData.length; i++) {
                        var item = WebSocketServer.tempData[i];
                        if (item.curPrjName === temp.curPrjName) {
                            WebSocketServer.tempData.splice(i, 1, temp);
                            break;
                        }
                    }
                    WebSocketServer.tempData.push(temp);
                    var fn = (function(emmitter, cmdData, curPtName) {
                        return function() {
                            var func = emmitter.MeasurePoint;
                            func.call(emmitter, cmdData, curPtName);
                        };
                    })(emmitter, cmdData, temp.curPtName);
                    bufferCaller.add(fn, cmdData.Target);

                } else if (msg.indexOf('距离') >= 0) {
                    var matches = WebSocketServer.tempData.filter(function(item, index) {
                        return item.curPrjName === cmdData.Target;
                    });
                    if (matches.length === 0) {
                        return;
                    }
                    var match = matches[0];
                    var re_array = msg.split(':');
                    match.curPtValue = parseFloat(re_array[1].slice(0, re_array[1].length - 1));
                    var fn = (function(emmitter, cmdData, name, value) {
                        return function() {
                            var func = emmitter.MeasureValue;
                            func.call(emmitter, cmdData, name, value);
                        };
                    })(emmitter, cmdData, match.curPtName, match.curPtValue);
                    bufferCaller.add(fn, cmdData.Target);
                }
            }


            ioSocket.on('connection', function(socket) {
                var client = WebClients.createNew(socket);
                WebSocketServer.WebClientList.push(client);
                client.OnGetProjects = function() {
                    console.log('try to get all projects!');
                    redisClientDataTransfer.get(redisNameSpace + ":prjList", (function() {
                        return function(err, reply) {
                            if (err) {
                                console.log(err);
                                return;
                            };
                            var prjList = JSON.parse(reply);
                            client.EmitData('GetProjects', prjList);
                        };
                    })(client));
                };
                client.OnCommand = function(cmdData) {
                    redisClientPublisher.publish(redisNameSpace + ':cmdFromWeb', JSON.stringify(cmdData));
                };
                client.OnDisConnect = function() {
                    for (var i = 0; i < WebSocketServer.WebClientList.length; i++) {
                        if (WebSocketServer.WebClientList[i].Id === client.Id) {
                            WebSocketServer.WebClientList.splice(i, 1);
                            break;
                        }
                    }
                };
            });


        }
    };
    return WebSocketServer;
};

exports.WebSocketServer = WebSocketServer;
